{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 파일들을 Hub로 푸시하기"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "🤗 Diffusers는 모델, 스케줄러 또는 파이프라인을 Hub에 업로드할 수 있는 `PushToHubMixin`을 제공합니다. 이는 Hub에 당신의 파일을 저장하는 쉬운 방법이며, 다른 사람들과 작업을 공유할 수도 있습니다. 실제적으로 `PushToHubMixin`가 동작하는 방식은 다음과 같습니다:\n",
    "\n",
    "1. Hub에 리포지토리를 생성합니다.\n",
    "2. 나중에 다시 불러올 수 있도록 모델, 스케줄러 또는 파이프라인 파일을 저장합니다.\n",
    "3. 이러한 파일이 포함된 폴더를 Hub에 업로드합니다.\n",
    "\n",
    "이 가이드는 `PushToHubMixin`을 사용하여 Hub에 파일을 업로드하는 방법을 보여줍니다.\n",
    "\n",
    "먼저 액세스 [토큰](https://huggingface.co/settings/tokens)으로 Hub 계정에 로그인해야 합니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from huggingface_hub import notebook_login\n",
    "\n",
    "notebook_login()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 모델"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모델을 허브에 푸시하려면 `push_to_hub()`를 호출하고 Hub에 저장할 모델의 리포지토리 id를 지정합니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from diffusers import ControlNetModel\n",
    "\n",
    "controlnet = ControlNetModel(\n",
    "    block_out_channels=(32, 64),\n",
    "    layers_per_block=2,\n",
    "    in_channels=4,\n",
    "    down_block_types=(\"DownBlock2D\", \"CrossAttnDownBlock2D\"),\n",
    "    cross_attention_dim=32,\n",
    "    conditioning_embedding_out_channels=(16, 32),\n",
    ")\n",
    "controlnet.push_to_hub(\"my-controlnet-model\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모델의 경우 Hub에 푸시할 가중치의 [*변형*](https://huggingface.co/docs/diffusers/main/ko/using-diffusers/loading#checkpoint-variants)을 지정할 수도 있습니다. 예를 들어, `fp16` 가중치를 푸시하려면 다음과 같이 하세요:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "controlnet.push_to_hub(\"my-controlnet-model\", variant=\"fp16\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`push_to_hub()` 함수는 모델의 `config.json` 파일을 저장하고 가중치는 `safetensors` 형식으로 자동으로 저장됩니다.\n",
    "\n",
    "이제 Hub의 리포지토리에서 모델을 다시 불러올 수 있습니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = ControlNetModel.from_pretrained(\"your-namespace/my-controlnet-model\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 스케줄러"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "스케줄러를 허브에 푸시하려면 `push_to_hub()`를 호출하고 Hub에 저장할 스케줄러의 리포지토리 id를 지정합니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from diffusers import DDIMScheduler\n",
    "\n",
    "scheduler = DDIMScheduler(\n",
    "    beta_start=0.00085,\n",
    "    beta_end=0.012,\n",
    "    beta_schedule=\"scaled_linear\",\n",
    "    clip_sample=False,\n",
    "    set_alpha_to_one=False,\n",
    ")\n",
    "scheduler.push_to_hub(\"my-controlnet-scheduler\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`push_to_hub()` 함수는 스케줄러의 `scheduler_config.json` 파일을 지정된 리포지토리에 저장합니다.\n",
    "\n",
    "이제 허브의 리포지토리에서 스케줄러를 다시 불러올 수 있습니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scheduler = DDIMScheduler.from_pretrained(\"your-namepsace/my-controlnet-scheduler\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 파이프라인"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모든 컴포넌트가 포함된 전체 파이프라인을 Hub로 푸시할 수도 있습니다. 예를 들어, 원하는 파라미터로 `StableDiffusionPipeline`의 컴포넌트들을 초기화합니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from diffusers import (\n",
    "    UNet2DConditionModel,\n",
    "    AutoencoderKL,\n",
    "    DDIMScheduler,\n",
    "    StableDiffusionPipeline,\n",
    ")\n",
    "from transformers import CLIPTextModel, CLIPTextConfig, CLIPTokenizer\n",
    "\n",
    "unet = UNet2DConditionModel(\n",
    "    block_out_channels=(32, 64),\n",
    "    layers_per_block=2,\n",
    "    sample_size=32,\n",
    "    in_channels=4,\n",
    "    out_channels=4,\n",
    "    down_block_types=(\"DownBlock2D\", \"CrossAttnDownBlock2D\"),\n",
    "    up_block_types=(\"CrossAttnUpBlock2D\", \"UpBlock2D\"),\n",
    "    cross_attention_dim=32,\n",
    ")\n",
    "\n",
    "scheduler = DDIMScheduler(\n",
    "    beta_start=0.00085,\n",
    "    beta_end=0.012,\n",
    "    beta_schedule=\"scaled_linear\",\n",
    "    clip_sample=False,\n",
    "    set_alpha_to_one=False,\n",
    ")\n",
    "\n",
    "vae = AutoencoderKL(\n",
    "    block_out_channels=[32, 64],\n",
    "    in_channels=3,\n",
    "    out_channels=3,\n",
    "    down_block_types=[\"DownEncoderBlock2D\", \"DownEncoderBlock2D\"],\n",
    "    up_block_types=[\"UpDecoderBlock2D\", \"UpDecoderBlock2D\"],\n",
    "    latent_channels=4,\n",
    ")\n",
    "\n",
    "text_encoder_config = CLIPTextConfig(\n",
    "    bos_token_id=0,\n",
    "    eos_token_id=2,\n",
    "    hidden_size=32,\n",
    "    intermediate_size=37,\n",
    "    layer_norm_eps=1e-05,\n",
    "    num_attention_heads=4,\n",
    "    num_hidden_layers=5,\n",
    "    pad_token_id=1,\n",
    "    vocab_size=1000,\n",
    ")\n",
    "text_encoder = CLIPTextModel(text_encoder_config)\n",
    "tokenizer = CLIPTokenizer.from_pretrained(\"hf-internal-testing/tiny-random-clip\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모든 컴포넌트들을 `StableDiffusionPipeline`에 전달하고 `push_to_hub()`를 호출하여 파이프라인을 Hub로 푸시합니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "components = {\n",
    "    \"unet\": unet,\n",
    "    \"scheduler\": scheduler,\n",
    "    \"vae\": vae,\n",
    "    \"text_encoder\": text_encoder,\n",
    "    \"tokenizer\": tokenizer,\n",
    "    \"safety_checker\": None,\n",
    "    \"feature_extractor\": None,\n",
    "}\n",
    "\n",
    "pipeline = StableDiffusionPipeline(**components)\n",
    "pipeline.push_to_hub(\"my-pipeline\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`push_to_hub()` 함수는 각 컴포넌트를 리포지토리의 하위 폴더에 저장합니다. 이제 Hub의 리포지토리에서 파이프라인을 다시 불러올 수 있습니다:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pipeline = StableDiffusionPipeline.from_pretrained(\"your-namespace/my-pipeline\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 비공개"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모델, 스케줄러 또는 파이프라인 파일들을 비공개로 두려면 `push_to_hub()` 함수에서 `private=True`를 설정하세요:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "controlnet.push_to_hub(\"my-controlnet-model-private\", private=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "비공개 리포지토리는 본인만 볼 수 있으며 다른 사용자는 리포지토리를 복제할 수 없고 리포지토리가 검색 결과에 표시되지 않습니다. 사용자가 비공개 리포지토리의 URL을 가지고 있더라도 `404 - Sorry, we can't find the page you are looking for`라는 메시지가 표시됩니다. 비공개 리포지토리에서 모델을 로드하려면 [로그인](https://huggingface.co/docs/huggingface_hub/quick-start#login) 상태여야 합니다."
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}
